package com.zhajh.view;

import java.util.ArrayList;

import org.json.JSONException;
import org.json.JSONObject;

import com.zhajh.R;
import com.zhajh.utils.Const;
import com.zhajh.utils.Player;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

public class GameView extends SurfaceView implements SurfaceHolder.Callback
{
    private static final int MIN_PLAYER_NUM = 2;
    private static final int MAX_PLAYER_NUM = 7;

    private static final int PLAYER_1 = 0;	// 左下
    private static final int PLAYER_2 = 1;	// 左上
    private static final int PLAYER_3 = 2;	// 右上
    private static final int PLAYER_4 = 3;	// 右下
    private static final int PLAYER_5 = 4;	//
    private static final int PLAYER_6 = 5;	//
    private static final int PLAYER_ME = MAX_PLAYER_NUM-1;

    private static final int PLAYER_INFO_W = 90;	// 基本信息区
    private static final int PLAYER_INFO_H = 120;
    private static final int MARGIN_LEFT = 30;
    private static final int MARGIN_TOP = 20;
    private static final int MARGIN_RIGHT = 30+PLAYER_INFO_W;
    private static final int MARGIN_BOTTOM = 50+PLAYER_INFO_H;

    private SurfaceHolder m_SurfaceHolder = null;
    private ArrayList<Player> mPlayerList = new ArrayList<Player>();
    private Player mPlayerMe = null;

    private int mHallId = 0;
    private int mRoomId = 0;
    private int mTableId = 0;
    private int mTableStatus = 0;
    private int mSingleMoney = 0;
    private int mTotalMoney = 0;
    private int mTurnNum = 0;

	public GameView(Context context) {
		super(context);
		init(context);
	}

	public GameView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public GameView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}

	private void init(Context context)
	{
	    m_SurfaceHolder = this.getHolder();
        m_SurfaceHolder.addCallback(this);

        this.setOnTouchListener(m_TouchListener);

        for (int i=0; i<MAX_PLAYER_NUM; i++)
        {
            mPlayerList.add(new Player(context));
        }

        mPlayerMe = mPlayerList.get(PLAYER_ME);
        //mPlayerMe.setInfo("Jerry", R.drawable.head_boy, 10000);
	}

	/*
     * 控件创建完成之后，在显示之前都会调用这个方法，此时可以获取控件的大小 并得到中心坐标和坐标轴圆心所在的点。
     */
    @Override
    public void onSizeChanged(int w, int h, int oldw, int oldh) {
        //YyttLog.log("neww="+w+", oldw="+oldw);
        //YyttLog.log("newh="+h+", oldh="+oldh);
        //LrcUtil.onSizeChanged(w, h);

        int x1 = MARGIN_LEFT;
        int x2 = w-MARGIN_RIGHT;
        int y1 = h-MARGIN_BOTTOM;
        int y2 = MARGIN_TOP;
        int y3 = (y1+y2)/2;
        int iw = PLAYER_INFO_W;
        int ih = PLAYER_INFO_H;

    	mPlayerList.get(PLAYER_1).setBaseRect(x1, y1, iw, ih, Player.Direction.RIGHT);
    	mPlayerList.get(PLAYER_2).setBaseRect(x1, y3, iw, ih, Player.Direction.RIGHT);
    	mPlayerList.get(PLAYER_3).setBaseRect(x1, y2, iw, ih, Player.Direction.RIGHT);
    	mPlayerList.get(PLAYER_4).setBaseRect(x2, y2, iw, ih, Player.Direction.LEFT);
    	mPlayerList.get(PLAYER_5).setBaseRect(x2, y3, iw, ih, Player.Direction.LEFT);
    	mPlayerList.get(PLAYER_6).setBaseRect(x2, y1, iw, ih, Player.Direction.LEFT);
    	mPlayerMe.setBaseRect((w-iw)/2, h-ih, iw, ih, Player.Direction.RIGHT);

        // 背景透明
        this.setZOrderOnTop(true);
        this.getHolder().setFormat(PixelFormat.TRANSLUCENT);

        super.onSizeChanged(w, h, oldw, oldh);
    }

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		drawAll();
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
	}

	public void drawAll()
    {
		drawRect(null);
    }

	private void drawRect(Rect rect)
    {
        synchronized (m_SurfaceHolder)
        {
            Canvas canvas = null;

            if (rect != null)
            	canvas = m_SurfaceHolder.lockCanvas(rect);
            else
            	canvas = m_SurfaceHolder.lockCanvas();

            if (canvas == null)
            {
                return;
            }

            //canvas.drawColor(CLEAR_BG_COLOR);
            canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

            Paint paint = new Paint();

            paint.setAntiAlias(true);
            paint.setColor(Color.RED);
            paint.setTextSize(24);

            // 居中对齐
            paint.setTextAlign(Align.CENTER);

            FontMetrics fontMetrics = paint.getFontMetrics();
            float fontHeight = fontMetrics.bottom - fontMetrics.top;    // 文字高度
            float textBaseY = (getHeight() + fontHeight)/2 - fontMetrics.bottom;  // 文字baseline

            //canvas.drawText(msg, getWidth()/2, textBaseY, paint);

            for (Player player: mPlayerList)
            {
            	player.draw(canvas);
            }

            if (mPlayerMe.getStatus() == Player.Status.UNRIPE)
            {

            }

            m_SurfaceHolder.unlockCanvasAndPost(canvas);
        }
    }

    OnTouchListener m_TouchListener = new OnTouchListener()
    {
        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
        	//drawAll();
        	return false;
        }
    };

    // mPlayerMe
    public void setMyInfo(JSONObject jsonInfo) throws JSONException
    {
        mPlayerMe.setInfo(jsonInfo);
        Rect rect = mPlayerMe.baseRect();
        drawRect(rect);
    }

    public void setAllInfo(JSONObject info) throws JSONException
    {
	    mHallId = info.getInt("hall_id");
        mRoomId = info.getInt("room_id");
        mTableId = info.getInt("table_id");
        int seatId = info.getInt("seat_id");
        mPlayerMe.setServerSeatId(seatId);

        String tableInfo = info.getString("table_info");
        JSONObject obj = new JSONObject(tableInfo);
        mTableStatus = obj.getInt("status");
        mSingleMoney = obj.getInt("single_money");
        mTotalMoney = obj.getInt("total_money");
        mTurnNum = obj.getInt("turn_num");

        for (int i=0; i<MAX_PLAYER_NUM; i++)
        {
        	if (i != seatId)
        	{
        		int j = mapServer2ClientId(i, seatId);
        		mapPlayer(obj, i, j);
        	}
        }

		drawAll();
    }

    public int mapServer2ClientId(int serverId, int serverIdMe)
    {
    	int idOffset = serverId - serverIdMe;

    	if (idOffset <= 0)
    	{
    		return PLAYER_ME + idOffset;
    	}
    	else
    	{
    		return idOffset - 1;
    	}
    }

    public int mapClient2ServerId(int clientId, int serverIdMe)
    {
    	int serverId = clientId - PLAYER_ME + serverIdMe;

    	if (serverId < 0)
    	{
    		serverId = clientId + 1 + serverIdMe;
    	}

    	return serverId;
    }

    private void mapPlayer(JSONObject obj, int serverId, int clientId) throws JSONException
    {
        String ps = "p"+serverId;
        Player player = mPlayerList.get(clientId);

        if (obj.has(ps))
        {
    		String pi = obj.getString(ps);
    		JSONObject jsonPlayer = new JSONObject(pi);
    		player.setInfo(jsonPlayer);
        }
        else
        {
            player.clear();
        }
    }

    public void procOtherPlayerChanged(int funcId, JSONObject json) throws JSONException
    {
        int serverId = json.getInt("seat_id");
        int mySeatId = mPlayerMe.getServerSeatId();
        int clientId = mapServer2ClientId(serverId, mySeatId);
        Player player = mPlayerList.get(clientId);

        switch (funcId)
		{
		case Const.FUNC_OTHER_PLAYER_ADD:
			player.setInfo(json);
			break;

        case Const.FUNC_OTHER_PLAYER_EXIT:
            player.clear();
            break;

        case Const.FUNC_OTHER_PLAYER_READY:
            player.ready();
            break;

		default:
			break;
		}

        Rect rect = player.rect();
        drawRect(rect);
    }

    public void idleMe()
    {
    	mPlayerMe.idle();
    	drawRect(mPlayerMe.statusRect());
    }

    public void readyMe()
    {
    	mPlayerMe.ready();
    	drawRect(mPlayerMe.statusRect());
    	//drawAll();
    }

    public void playMe()
    {
    	mPlayerMe.play();
    	drawRect(mPlayerMe.rect());
    }
}
